class ActiveRecord::Base
  def update_attribute(name, value)
    update_attributes(name => value)
  end

  def update_attributes(new_attributes)
    return if new_attributes.nil?
    attributes = new_attributes.dup
    attributes.stringify_keys!
    self.attributes = attributes

    update(attributes)
  end

  private
    def update(attrs = nil)
      connection.update(
        "UPDATE #{self.class.table_name} " +
        "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, attrs))} " +
        "WHERE #{self.class.primary_key} = #{quote(id)}",
        "#{self.class.name} Update"
      )
        
      return true
    end

    def attributes_with_quotes(include_primary_key = true, attrs = nil)
      (attrs || attributes).inject({}) do |quoted, (name, value)|
        if column = column_for_attribute(name)
          quoted[name] = quote(value, column) unless !include_primary_key && column.primary
        elsif assoc = self.class.reflect_on_association(name.to_sym)
          quoted[assoc.primary_key_name] = read_attribute(assoc.primary_key_name) if assoc.macro == :belongs_to
        end
        quoted
      end
    end
end

module ActiveRecord
  module ValidationsFix
    def self.included(base) # :nodoc:
      base.class_eval do
        alias_method :update_attributes_without_validation, :update_attributes
        alias_method :update_attributes, :update_attributes_with_validation
        public :update_attributes
      end
    end

    def update_attribute(name, value)
      update_attributes(name => value)
    end

    def update_attributes(new_attributes)
      return if new_attributes.nil?
      attributes = new_attributes.dup
      attributes.stringify_keys!
      self.attributes = attributes

      update(attributes)
    end
    def update_attributes_with_validation(new_attributes)
      return if new_attributes.nil?
      attributes = new_attributes.dup
      attributes.stringify_keys!
      self.attributes = attributes

      if valid?
        update_attributes_without_validation(attributes)
      else
        return false
      end
    end

    private
      def update(attrs = nil)
        connection.update(
          "UPDATE #{self.class.table_name} " +
          "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, attrs))} " +
          "WHERE #{self.class.primary_key} = #{quote(id)}",
          "#{self.class.name} Update"
        )
        
        return true
      end

      def attributes_with_quotes(include_primary_key = true, attrs = nil)
        (attrs || attributes).inject({}) do |quoted, (name, value)|
          if column = column_for_attribute(name)
            quoted[name] = quote(value, column) unless !include_primary_key && column.primary
          elsif assoc = self.class.reflect_on_association(name.to_sym)
            quoted[assoc.primary_key_name] = read_attribute(assoc.primary_key_name) if assoc.macro == :belongs_to
          end
          quoted
        end
      end
  end
end

ActiveRecord::Base.class_eval do
  include ActiveRecord::ValidationsFix
end
